package ru.ifmo.ct.network.brafs.file;

import java.io.*;
import java.util.Arrays;

/**
 * @author Roman Kolganov
 *         21.04.12
 */
public class HDDFileHolder implements FileHolder {

    private static String escapeSlashes(String filename) {
        String[] parts = filename.split("/");
        StringBuilder result = new StringBuilder((parts.length - 1) + ".");
        for (int i = 0; i < parts.length - 1; i++) {
            result.append(parts[i].length());
            result.append('.');
            result.append(parts[i]);
        }
        return result.append(parts[parts.length - 1]).toString();
    }

    /*private static String decode(String escapedFilename) {
        StringBuilder result = new StringBuilder();
        int dotPosition = escapedFilename.indexOf('.');
        int partNum = Integer.parseInt(escapedFilename.substring(0, dotPosition));
        escapedFilename = escapedFilename.substring(dotPosition + 1);
        for (int i = 0; i < partNum; i++) {
            dotPosition = escapedFilename.indexOf('.');
            int length = Integer.parseInt(escapedFilename.substring(0, dotPosition));
            result.append(escapedFilename.substring(dotPosition + 1, dotPosition + length + 1));
            result.append('/');
            escapedFilename = escapedFilename.substring(dotPosition + length + 1);
        }
        return result.append(escapedFilename).toString();
    }*/

    @Override
    public byte[] get(String fileId, long segmentId) {
        File file = new File(escapeSlashes(fileId) + "." + segmentId);
        byte[] result = new byte[(int) file.length()];
        try {
            FileInputStream in = new FileInputStream(file);
            in.read(result);
            in.close();
        } catch (IOException e) {
            return null;
        }
        return result;
    }

    @Override
    public int hash(String fileId, long segmentId) {
        byte[] data = get(fileId, segmentId);
        if (data == null) {
            return 0;
        }
        int hash = Arrays.hashCode(data);
        return hash == 0 ? 1 : hash;
    }

    @Override
    public void put(String fileId, long segmentId, byte[] data) {
        try {
            FileOutputStream file = new FileOutputStream(escapeSlashes(fileId) + "." + segmentId);
            file.write(data);
            file.close();
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    @Override
    public void delete(String fileId, long segmentId) {
        File file = new File(escapeSlashes(fileId) + "." + segmentId);
        file.delete();
    }
}
